from typing import Union

from PySide6.QtCore import QUrl, QTimer, Qt, Signal
from PySide6.QtGui import QCursor
from PySide6.QtMultimedia import QMediaPlayer
from PySide6.QtWidgets import QWidget, QVBoxLayout

from .player_bar import PlayerBar
from ..common import GifIcon, Icon
from ..widgets import VideoWidget, IconWidget, ImageLabel


class ForegroundWidget(QWidget):
    clicked = Signal()
    def __init__(self, parent=None):
        super().__init__(parent)
        self.vBox = QVBoxLayout(self)
        self.iconWidget = IconWidget(Icon.PLAYER, self)
        self.iconWidget.setFixedSize(150, 150)
        self.iconWidget.clicked.connect(self.clicked)
        self.vBox.addWidget(self.iconWidget, 0, Qt.AlignmentFlag.AlignCenter)


class VideoPlayerWidget(VideoWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.foregroundImage = ForegroundWidget(self)
        self.progressRing = ImageLabel(self)
        self.playerBar = PlayerBar(self)
        self.timer = QTimer(self)

        self.timer.setSingleShot(True)
        self.timer.setInterval(3000)
        self.timer.timeout.connect(self.__hidePlayer)

        self.playerBar.setVideoOutput(self)
        self.playerBar.fullScreenChanged.connect(self.setFullScreen)
        self.playerBar.player.mediaStatusChanged.connect(self.__onMediaStatusChanged)
        self.foregroundImage.clicked.connect(self.play)

        self.progressRing.setMovie(GifIcon.LOADING.movie())
        self.progressRing.setFixedSize(60, 30)
        self.progressRing.move((self.width() - self.progressRing.width()) // 2,
                               (self.height() - self.progressRing.height()) // 2)
        self.playerBar.move(5, self.height() - self.playerBar.height() - 5)
        self.progressRing.hide()

        self.setMouseTracking(True)
        self.playerBar.installEventFilter(self)
        self.foregroundImage.raise_()
        self.foregroundImage.show()

    def __onMediaStatusChanged(self, status: QMediaPlayer.MediaStatus):
        if status == QMediaPlayer.MediaStatus.LoadingMedia:
            self.progressRing.movie().start()
            self.progressRing.show()
        elif status == QMediaPlayer.MediaStatus.LoadedMedia:
            self.progressRing.movie().stop()
            self.progressRing.hide()
            if self.foregroundImage.isVisible():
                self.foregroundImage.hide()

    def setSource(self, source: Union[QUrl, str]):
        self.playerBar.setSource(source)

    def play(self):
        self.playerBar.player.play()

    def pause(self):
        self.playerBar.player.pause()

    def stop(self):
        self.playerBar.player.stop()

    def toggle(self):
        self.playerBar.player.toggle()

    def resizeEvent(self, event, /):
        self.playerBar.resize(self.width() - 10, self.playerBar.height())
        self.playerBar.move(5, self.height() - self.playerBar.height() - 5)
        self.progressRing.move((self.width() - self.progressRing.width()) // 2,
                               (self.height() - self.progressRing.height()) // 2)
        self.foregroundImage.setGeometry(0, 0, self.width(), self.height())
        super().resizeEvent(event)

    def leaveEvent(self, event, /):
        self.__hidePlayer()

    def enterEvent(self, event, /):
        self.__showPlayer()

    def mousePressEvent(self, event, /):
        self.__showPlayer()

    def mouseMoveEvent(self, event, /):
        self.__showPlayer()

    def __hidePlayer(self):
        self.playerBar.hide()
        self.timer.stop()
        self.setCursor(Qt.CursorShape.BlankCursor)

    def __showPlayer(self):
        self.playerBar.show()
        self.timer.start()
        self.setCursor(Qt.CursorShape.ArrowCursor)
